package com.tuzhi.base.service;

import com.tuzhi.base.function.SFunction;
import com.tuzhi.base.jpa.domain.Pager;
import com.tuzhi.base.jpa.domain.WhereConditionBO;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.lang.Nullable;

import java.util.List;
import java.util.Optional;

public interface BaseService<T, ID> {

    T save(T t);

    void delete(T t);

    int delete4Status(ID id);


    int disable4Status(ID id);

    int enable4Status(ID id);

    void deleteById(ID id);

    T findById(ID id);

    T findOne(WhereConditionBO whereConditionBO);

    List<T> findAllByWhereConditionBO(WhereConditionBO whereConditionBO);

    Page<T> findPage(PageRequest pageRequest, WhereConditionBO whereConditionBO);

    Page<T> findPage(PageRequest pageRequest, T t);

    Page<T> findPage(PageRequest pageRequest, T t, String orderName, String orderType);

    /**
     * 获取所有启用状态的数据集合
     *
     * @return
     */
    List<T> findAll4Enable();

    List<T> findAll(T t);

    List<T> findAll(T t, String orderName, String orderType);

    /**
     * 通过指定属性，属性值查找一条记录，必须是唯一记录的
     *
     * @param propertyName
     * @param propertyValue
     * @return
     */
    T findOne(String propertyName, Object propertyValue);

    T get(ID pk);

    Pager<T> listPager(Pager<T> pager);

    /**
     * 必须保证数据是在查询条件满足下唯一存在或不存在（若存在多条，则会异常）
     *
     * @param whereConditionBO
     * @return
     */
    T getOneUnique(WhereConditionBO whereConditionBO);


    /**
     * 通过指定属性，属性值查找一条记录，必须是唯一记录的（若存在多条，则会异常）
     *
     * @param propertyName
     * @param propertyValue
     * @return
     */
    T getOneUnique(SFunction<? super T, ?> propertyName, Object propertyValue);


    Optional<T> findOne(@Nullable Specification<T> spec);

    List<T> findAll(@Nullable Specification<T> spec);

    Page<T> findAll(@Nullable Specification<T> spec, Pageable pageable);

    List<T> findAll(@Nullable Specification<T> spec, Sort sort);

    long count(@Nullable Specification<T> spec);

    T getOneUnique(@Nullable Specification<T> spec);

    <T> List<T> saveAll(List<T> list, Integer batchSize);

    <T> List<T> updateAll(List<T> list, Integer batchSize);

    <T> List<T> batchSaveAll(List<T> list, Integer batchSize);

    void deleteAll(Iterable<? extends T> entities);

    void deleteAllInBatch(Iterable<T> entities);

    void deleteAllByIdInBatch(Iterable<ID> ids);


}
